/**
 * File: PruneGraphDefaultController.java
 * Created by: mhaimel
 * Created on: Apr 21, 2010
 * CVS:  $Id: PruneGraphDefaultController.java 1.0 Apr 21, 2010 2:35:26 PM mhaimel Exp $
 */
package uk.ac.ebi.curtain.controller.graph;

import java.io.Serializable;
import java.util.List;

import uk.ac.ebi.curtain.controller.SingleSubmitController;
import uk.ac.ebi.curtain.model.graph.Arc;
import uk.ac.ebi.curtain.model.graph.Graph;
import uk.ac.ebi.curtain.model.graph.GraphAccess.ProcessEach;
import uk.ac.ebi.curtain.model.graph.curtain.CategoryReadInfo;
import uk.ac.ebi.curtain.model.graph.curtain.ContigInfo;
import uk.ac.ebi.curtain.model.graph.curtain.CurtainGraph;
import uk.ac.ebi.curtain.model.graph.curtain.ReadWrapper;

/**
 * @author mhaimel
 *
 */
public class FilterGraphByWeightController extends SingleSubmitController<Serializable, Serializable> {

	@Override
	protected void singleSubmit(List<Serializable> inputList) {
		CurtainGraph curtainGraph = getContext().getGraph();
		Graph<ContigInfo, ReadWrapper> graph = curtainGraph.getGraph();
		Integer categories = curtainGraph.getCategories();
		// reindex before starting
		graph.reindexArcs();
		graph.buildArcsIndex();
		getLog().info("Filter Arcs of Graph by weight ... ");
		filterArcs(graph, categories);
		// reindex 
		graph.buildArcsIndex();
		graph.reindexArcs();
		for(Serializable s : inputList){
			submit(s);
		}
	}
	
	private void filterArcs(Graph<ContigInfo, ReadWrapper> graph,Integer categories) {
		final double minQual = 30d; 
		graph.processArcs(new ProcessEach<Arc<ContigInfo,ReadWrapper>>() {
			
			@Override
			public Arc<ContigInfo, ReadWrapper> process(int idx,Arc<ContigInfo, ReadWrapper> arc) {
				if(null == arc) 
					return null;
				Integer cat = arc.getValue().getCategories();
				boolean valid = false;
				for(int i = 0; i < cat; ++i){
					CategoryReadInfo info = arc.getValue().getInfo(i);
					if(null != info){
						Integer multi = info.getMultiplicity();
						Double sum = info.getWeightSum();
						double val = sum/multi;
						if(val < minQual){
							arc.getValue().forceSetCategoryReadInfo(i, null);
						}else {
							valid = true;
						}
					}
				}
				if(!valid){
					arc = null;
				}  
				return arc;
			}
		});
		getLog().debug("Done");
	}

}
